import axios, {
  AxiosError,
  AxiosResponse,
  InternalAxiosRequestConfig,
  AxiosRequestConfig,
} from 'axios'
import { useToastStore } from '../stores/toast-helper'
import { useAuthStore } from '@/stores/auth'
import { BASE_API_URL } from '@/assets/static'
import { useLoadingStore } from '@/stores/loading-store'

// 扩展 AxiosRequestConfig 类型
declare module 'axios' {
  interface AxiosRequestConfig {
    loadingText?: string
    skipLoading?: boolean
  }
}

// API 响应接口
export interface ApiResponse<T = any> {
  code: number
  data: T
  message: string
  statusText: string
}

// 显示提示的辅助函数
const showToast = (
  title: string,
  description?: string,
  variant: 'default' | 'destructive' = 'default',
) => {
  useToastStore.getState().show({ title, description, variant })
}

// 创建 axios 实例
const request = axios.create({
  baseURL: BASE_API_URL,
  // timeout: 15 * 1000,
  timeout: 6000 * 1000,
  headers: {
    'Content-Type': 'application/json',
  },
})

// 请求拦截器
request.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    if (config.headers?.['skip-loading'] || config.skipLoading) {
      config.skipLoading = true
      if (config.headers.hasOwnProperty('skip-loading')) {
        delete config.headers['skip-loading']
      }
    } else {
      let loadingText = config?.loadingText || ''
      if (config.headers.hasOwnProperty('loading-text')) {
        loadingText = config.headers['loading-text'] as string || ''
        delete config.headers['loading-text']
      }
      useLoadingStore.getState().increment(loadingText)
    }

    const token = useAuthStore.getState().token
    if (token && config.headers) {
      config.headers['Authorization'] = `Bearer ${token}`
    }

    return config
  },
  (error: AxiosError) => {
    if (!error.config?.skipLoading) {
      useLoadingStore.getState().decrement()
    }
    showToast('请求错误', error.message, 'destructive')
    return Promise.reject(error)
  },
)

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    if (!response.config.skipLoading) {
      useLoadingStore.getState().decrement()
    }
    const { data } = response

    if (data.code === 200) {
      return data.data
    } else {
      showToast('', data.message, 'destructive')
      return Promise.reject(new Error(data.message))
    }
  },
  (error: AxiosError<ApiResponse>) => {
    if (!error.config?.skipLoading) {
      useLoadingStore.getState().decrement()
    }
    if (error.response) {
      const { status } = error.response

      switch (status) {
        case 401:
          // 清除认证信息
          useAuthStore.getState().clearAuth()
          useAuthStore.getState().redirectToLogin()
          break

        case 403:
          showToast('访问受限', '没有权限访问该资源', 'destructive')
          break

        case 404:
          showToast('资源不存在', '请求的资源不存在', 'destructive')
          break

        case 500:
          showToast('服务器错误', '服务器发生错误，请稍后重试', 'destructive')
          break

        default:
          showToast(
            '请求失败',
            error.response.data?.message || '未知错误',
            'destructive',
          )
      }
    } else if (error.request) {
      showToast('网络错误', '请检查您的网络连接', 'destructive')
    } else {
      showToast('配置错误', '请求配置发生错误', 'destructive')
    }

    return Promise.reject(error)
  },
)

// HTTP 方法封装
export const http = {
  get: <T = any>(url: string, config?: AxiosRequestConfig) =>
    request.get<any, T>(url, config),

  post: <T = any>(url: string, data?: any, config?: AxiosRequestConfig) =>
    request.post<any, T>(url, data, config),

  put: <T = any>(url: string, data?: any, config?: AxiosRequestConfig) =>
    request.put<any, T>(url, data, config),

  delete: <T = any>(url: string, config?: AxiosRequestConfig) =>
    request.delete<any, T>(url, config),

  upload: <T = any>(
    url: string,
    file: File,
    onUploadProgress?: (progressEvent: any) => void,
  ) => {
    const formData = new FormData()
    formData.append('file', file)

    return request.post<any, T>(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      onUploadProgress,
    })
  },
}

export default request
